#ifndef __THREAD_HPP__
#define __THREAD_HPP__

#include<iostream>
#include<pthread.h>
#include<unistd.h>
#include<string>
#include<functional>
#include<sys/syscall.h>
#include"Logger.hpp"
#define get_lwp_id() syscall(SYS_gettid)

using func_t =std::function<void(const std::string& name)>;
const std::string threadnamedefault="thread-0";

class Thread
{
public:
    Thread(func_t func,const std::string& name=threadnamedefault)
        :_name(name)
        ,_func(func)
        ,_isrunning(false)
    {
        LOG(Loglevel::INFO)<<_name<<" create thread obj success";
        //std::cout<<"create thread success"<<std::endl;
    }
    //类内函数形参实际上还有一个this指针，所以把这个函数放到pthread_create中会报错
    // void* start_routine(void* args)
    // {

    // }
    static void* start_routine(void* args)
    {
        Thread* self=static_cast<Thread*>(args);
        self->_isrunning=true;
        self->_lwpid=get_lwp_id();//宏封装系统调用
        self->_func(self->_name);//线程回调转而去执行外部提供的方法
        //返回
        pthread_exit((void*)0);
    }
    void Start(){
        int n=pthread_create(&_tid,nullptr,start_routine,this);//this传给args
        //非静态成员函数都有this指针
        //this 指针指向调用该成员函数的那个特定对象实例
        if(n==0)
        {
            //成功
            LOG(Loglevel::INFO)<<_name<<" run thread success";
        }
    }
    
    //检测线程结束并且回收
    void Join(){
        //如果没有启动
        if(!_isrunning)
            return;

        int n=pthread_join(_tid,nullptr);
        if(n==0)
        {
            LOG(Loglevel::INFO)<<_name<<"  pthread_join success";
        }
    }
    void Stop()
    {
        int n = pthread_cancel(_tid); // 太简单粗暴了
        (void)n;
    }

    ~Thread()
    {
    }

private:
    bool _isrunning;
    pthread_t _tid;
    pid_t _lwpid;
    std::string _name;
    func_t _func;
};

#endif